#
#   url_encryption.py
#   journalismManger
#
#   Created by luoxh on 2019-07-17-11:41.
#   Copyright © 2019 luoxh. All rights reserved.
#
import hashlib
import json
import re

from flask import (request, )

from src import (app, CustomException, CustomStatus, )
from ..config import BaseConfig


@app.before_request
def url_encryption():
    """
    url参数加密请求
    :return: 返回错误信息，或者错误
    """

    # 1. 跳过本地验证、白名单、admin
    if request.headers.environ['REMOTE_ADDR'] in ['127.0.0.1']: return
    if request.path in BaseConfig.white_list or '/notify/' in request.path: return
    if re.match('^/admin.*$', request.path): return

    # 2. 验证参数
    version, old_key, platform = get_url_params()

    ## 老版本跳过校验
    if (platform == 'android' and version < '1.0.5') or (platform == 'ios' and version < '1.0.3'): return

    if platform == 'ios':
        m_id = request.args.get('m_id', -1, int)
        if m_id != -1: platform = 'ios_other'  # 越狱

    if platform not in ['android', 'ios', 'ios_other'] or version not in app.config['API_SECRET_KEYS'].get(platform,
                                                                                                           {}):
        raise CustomException(CustomStatus.BAD_REQUEST)

    start_verify(version, old_key, platform)


def get_url_params():
    try:
        version = request.args['v']
        old_key = request.args['sn']
        platform = request.args['platform']
    except KeyError: raise CustomException(CustomStatus.PARAMETER_ERROR)
    else: return version, old_key, platform


def start_verify(version, old_key, platform):
    api_key = app.config['API_SECRET_KEYS'].get(platform).get(version)
    args = list()
    get_args = request.args
    post_args = request.form

    for key in get_args:
        if key.lower() != 'sn':
            for v in get_args.getlist(key): arg_str = '%s=%s' % (key, v);args.append(arg_str)

    for key in post_args:
        if key.lower() != 'sn':
            for v in post_args.getlist(key): arg_str = '%s=%s' % (key, v);args.append(arg_str)

    sorted_args = sorted(args)
    sorted_args.append(api_key)

    params = ''.join(sorted_args)
    md5_str = hashlib.md5(bytes(params.encode('utf-8'))).hexdigest()
    new_key = md5_str[:7]

    if old_key.lower() != new_key.lower():
        tmp_s = json.dumps(
            {'get_params': request.args.to_dict(), 'post_params': request.data.to_dict(), 'sorted_params': params,
             # 'sorted_params_encoded': unquote(params.encode('utf8')),
             'server_sn' : new_key.lower(), 'client_sn': old_key.lower(), 'server_md5': md5_str, })
        if app.config['DEBUG']: print('\r\n Error Verify >>>', tmp_s); raise CustomException(tmp_s)
        else: raise CustomException(CustomStatus.VERIFICATION_FAILED)
